#include "WFT0375_spi.h"

static uint8_t lut_v[15] = { 0x4A, 0x4A, 0x01, 0x8A, 0x8A, 0x01, 0x4A, 0x4A,
        0x01, 0x8A, 0x8A, 0x01, 0x81, 0x81, 0x01 };
static uint8_t lut_kk[15] = { 0x8A, 0x8A, 0x01, 0x8A, 0x8A, 0x01, 0x4A, 0x4A,
        0x01, 0x4A, 0x4A, 0x01, 0x81, 0x81, 0x01 };
static uint8_t lut_ww[15] = { 0x4A, 0x4A, 0x01, 0x4A, 0x4A, 0x01, 0x8A, 0x8A,
        0x01, 0x8A, 0x8A, 0x01, 0x81, 0x81, 0x01 };
static uint8_t lut_add[15] = { 0x86, 0x86, 0x01, 0x46, 0x46, 0x01, 0x86, 0x86,
        0x01, 0x46, 0x46, 0x01, 0x81, 0x81, 0x01 };

void bit9WriteCmd(UINT8 d);
void bit9WriteData(UINT8 d);

void bit9Init(void) {
    GPIOA_ModeCfg(CS_PIN, GPIO_ModeOut_PP_5mA);
    GPIOA_ModeCfg(SCLK_PIN, GPIO_ModeOut_PP_5mA);
    GPIOA_ModeCfg(MOSI_PIN, GPIO_ModeOut_PP_5mA);
    GPIOA_ModeCfg(BUSY_PIN, GPIO_ModeIN_PU);
    GPIOA_ModeCfg(RST_N_PIN, GPIO_ModeOut_PP_5mA);
    GPIOA_ModeCfg(SHD_N_PIN, GPIO_ModeOut_PP_5mA);
    CS_H;
    MOSI_H;
    SCLK_L;
    RST_H;
    SHD_H;
}

void bit9WriteCmd(UINT8 u8_writedata) {
    CS_L;
    MOSI_L;
    SCLK_H;
    SCLK_L;
    for (UINT8 i = 0; i < 8; i++) {
        if (u8_writedata & 0x80)
            MOSI_H;
        else
            MOSI_L;
        SCLK_H;
        u8_writedata <<= 1;
        SCLK_L;
    }
    CS_H;
    MOSI_H;
    DelayUs(5);
}

void bit9WriteData(UINT8 u8_writedata) {
    CS_L;
    MOSI_H;
    SCLK_H;
    SCLK_L;
    for (UINT8 i = 0; i < 8; i++) {
        if (u8_writedata & 0x80)
            MOSI_H;
        else
            MOSI_L;
        SCLK_H;
        u8_writedata <<= 1;
        SCLK_L;
    }
    CS_H;
    MOSI_H;
    DelayUs(5);
}

void allWhite(void) {
    GPIOA_ResetBits(RST_N_PIN);       //set low pulse on RST_N for 110us
    DelayUs(110);
    GPIOA_SetBits(RST_N_PIN);

    bit9WriteCmd(0x04);                 //send Power On

    while (GPIOA_ReadPortPin(BUSY_PIN) == 0)    //Wait for BUSY_N high
    DelayMs(1);

    bit9WriteCmd(0x00);             //Send: Panel Setting (PANEL_SETTING - 0x00)
    bit9WriteData(0x0b);

    bit9WriteCmd(0x01);             //Send: Power Setting (POWER_SETTING - 0x01)
    bit9WriteData(0x46);
    bit9WriteData(0x46);

    bit9WriteCmd(0x03); //Send: Power Off Sequence Setting (POWER_OFF_SEQUENCE_SETTING - 0x03)
    bit9WriteData(0x00);

    bit9WriteCmd(0x30);   //Send: Frame Rate Control (FRAME_RATE_CONTROL - 0x30)
    bit9WriteData(0x02);

    bit9WriteCmd(0x20);                 //Send: LUTV (0x20)
    for (int i = 0; i < 15; i++) {
        bit9WriteData(lut_v[i]);
    }

    bit9WriteCmd(0x23);                 //Send:  LUT_KK (0x23)
    for (int i = 0; i < 15; i++) {
        bit9WriteData(lut_kk[i]);
    }

    bit9WriteCmd(0x26);                 //Send: LUT_WW (0x26)
    for (int i = 0; i < 15; i++) {
        bit9WriteData(lut_ww[i]);
    }

    bit9WriteCmd(0x18);
    for (int i = 0; i < 18; i++) {
        bit9WriteData(0xff);
    }

    bit9WriteCmd(0x1c);
    for (int i = 0; i < 18; i++) {
        bit9WriteData(0xff);
    }

    bit9WriteCmd(0x12);

    while (GPIOA_ReadPortPin(BUSY_PIN) == 0)
    DelayMs(1);

    bit9WriteCmd(0x02);
    bit9WriteData(0x03);

    while (GPIOA_ReadPortPin(BUSY_PIN) == 0)
    DelayMs(1);
}

void allBlack(void) {
    GPIOA_ResetBits(GPIO_Pin_11);
    DelayUs(110);
    GPIOA_SetBits(GPIO_Pin_11);

    bit9WriteCmd(0x04);

    while (GPIOA_ReadPortPin(BUSY_PIN) == 0)
    DelayMs(1);

    bit9WriteCmd(0x00);
    bit9WriteData(0x0b);

    bit9WriteCmd(0x01);
    bit9WriteData(0x46);
    bit9WriteData(0x46);

    bit9WriteCmd(0x03);
    bit9WriteData(0x00);

    bit9WriteCmd(0x30);
    bit9WriteData(0x02);

    bit9WriteCmd(0x20);                 //Send: LUTV (0x20)
    for (int i = 0; i < 15; i++) {
        bit9WriteData(lut_v[i]);
    }

    bit9WriteCmd(0x23);                 //Send:  LUT_KK (0x23)
    for (int i = 0; i < 15; i++) {
        bit9WriteData(lut_kk[i]);
    }

    bit9WriteCmd(0x26);                 //Send: LUT_WW (0x26)
    for (int i = 0; i < 15; i++) {
        bit9WriteData(lut_ww[i]);
    }

    bit9WriteCmd(0x18);
    for (int i = 0; i < 18; i++) {
        bit9WriteData(0x00);
    }

    bit9WriteCmd(0x1c);
    for (int i = 0; i < 18; i++) {
        bit9WriteData(0x00);
    }

    bit9WriteCmd(0x12);

    while (GPIOA_ReadPortPin(BUSY_PIN) == 0)
    DelayMs(1);

    bit9WriteCmd(0x02);
    bit9WriteData(0x03);

    while (GPIOA_ReadPortPin(BUSY_PIN) == 0)
    DelayMs(1);
}

void displayData(uint8_t *displayData) {

    bit9WriteCmd(0x04);
    DelayMs(100);
    //while (GPIOA_ReadPortPin(BUSY_PIN) == 0)
    //    DelayMs(1);

    bit9WriteCmd(0x00);
    bit9WriteData(0x0b);

    bit9WriteCmd(0x01);
    bit9WriteData(0x46);
    bit9WriteData(0x46);

    bit9WriteCmd(0x03);
    bit9WriteData(0x06);

    bit9WriteCmd(0x30);
    bit9WriteData(0x03);

    bit9WriteCmd(0x15); //Send (ONLY when not initialising): PARTIAL_DISPLAY_REFRESH - 0x15
    bit9WriteData(0x00);
    bit9WriteData(0x87);
    bit9WriteData(0x01);

    bit9WriteCmd(0x20);
    for (int i = 0; i < 15; i++) {
        bit9WriteData(lut_add[i]);
    }

    bit9WriteCmd(0x23);
    for (int i = 0; i < 15; i++) {
        bit9WriteData(lut_add[i]);
    }

    bit9WriteCmd(0x24);
    bit9WriteData(0x86);
    bit9WriteData(0x86);
    bit9WriteData(0x01);
    bit9WriteData(0x86);
    bit9WriteData(0x86);
    bit9WriteData(0x01);
    bit9WriteData(0x86);
    bit9WriteData(0x86);
    bit9WriteData(0x01);
    bit9WriteData(0x86);
    bit9WriteData(0x86);
    bit9WriteData(0x01);
    bit9WriteData(0x81);
    bit9WriteData(0x81);
    bit9WriteData(0x01);

    bit9WriteCmd(0x25);
    bit9WriteData(0x46);
    bit9WriteData(0x46);
    bit9WriteData(0x01);
    bit9WriteData(0x46);
    bit9WriteData(0x46);
    bit9WriteData(0x01);
    bit9WriteData(0x46);
    bit9WriteData(0x46);
    bit9WriteData(0x01);
    bit9WriteData(0x46);
    bit9WriteData(0x46);
    bit9WriteData(0x01);
    bit9WriteData(0x81);
    bit9WriteData(0x81);
    bit9WriteData(0x01);

    bit9WriteCmd(0x26);
    for (int i = 0; i < 15; i++) {
        bit9WriteData(lut_add[i]);
    }

    bit9WriteCmd(0x18);
    for (int i = 0; i < 17; i++) {
        bit9WriteData(displayData[i]);
    }
    bit9WriteData(0xff);

    bit9WriteCmd(0x12);

    while (GPIOA_ReadPortPin(BUSY_PIN) == 0)
    DelayMs(1);

    bit9WriteCmd(0x02);
    bit9WriteData(0x03);

    while (GPIOA_ReadPortPin(BUSY_PIN) == 0)
    DelayMs(1);
}
